package com.amigo.online.provider.video.service.impl;


import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.amigo.online.common.base.service.BaseService;
import com.amigo.online.common.core.response.Response;
import com.amigo.online.common.core.response.StatusCode;
import com.amigo.online.common.param.RedisKey;
import com.amigo.online.common.param.dto.video.MusicDto;
import com.amigo.online.common.param.dto.video.MusicQueryDto;
import com.amigo.online.common.param.result.MusicInfo;
import com.amigo.online.common.param.result.UserInfo;
import com.amigo.online.provider.video.common.ConstantValue;
import com.amigo.online.provider.video.common.GlobalController;
import com.amigo.online.provider.video.common.RwRedisService;
import com.amigo.online.provider.video.exception.MusicException;
import com.amigo.online.provider.video.exception.VideoException;
import com.amigo.online.provider.video.mapper.MusicCollectMapper;
import com.amigo.online.provider.video.mapper.MusicMapper;
import com.amigo.online.provider.video.model.entity.Music;
import com.amigo.online.provider.video.model.entity.MusicCollect;
import com.amigo.online.provider.video.service.MusicService;
import com.amigo.online.provider.video.service.RedisService;
import com.amigo.online.provider.video.service.VideoService;
import com.amigo.online.provider.video.util.ConvertUtil;
import com.google.common.base.Function;
import com.google.common.collect.Maps;

@Service
@Transactional(rollbackFor = Exception.class)
@SuppressWarnings({"unchecked", "rawtypes"})
public class MusicServiceImpl extends BaseService<Music> implements MusicService {

    @Autowired
    VideoService videoService;

    @Resource
    MusicMapper musicMapper;

    @Resource
    RedisService redisService;

    @Resource
    MusicCollectMapper musicCollectMapper;

    @Autowired
    RwRedisService rwRedisService;

    private static String MUSIC_COLLECT_KEY = RedisKey.MUSIC_COLLECT_REDIS_KEY;

    private static String MUSIC_KEY = RedisKey.MUSIC_REDIS_KEY;

    private static String MUSIC_ID_KEY = RedisKey.MUSIC_REDIS_ID_KEY;

    /**
     * 获取音乐列表
     *
     * @param page
     * @param size
     * @return
     */
    @Override
    public List<MusicInfo> getMusics(Long musicid, Integer page, Integer size) {

        UserInfo u = GlobalController.getNowUser();
        MusicQueryDto dto = new MusicQueryDto();
        MusicInfo currentMusicInfo = new MusicInfo();
        if (musicid != null) {
            dto.setUserId(u.getId());
            dto.setMusicId(musicid);
            Music music = musicMapper.queryById(dto);
            if (music != null) {
                BeanUtils.copyProperties(music, currentMusicInfo);
            }
        }

        Integer iOffset = (page - 1) * size;
        Response r = new Response();
        //调用redis公共查询方法
        List<Object> list = (List<Object>) redisService.listFromRedis(page, size, MUSIC_ID_KEY, MUSIC_KEY, r);
        int res = Integer.parseInt(r.getData().toString());
        if (res == 0) {
            // redis中存储的收藏状态没有实际意义，需要重新根据用户收藏情况重新判断
            List<Integer> collectList = (List) rwRedisService.lrange(MUSIC_COLLECT_KEY + u.getId(), 0, -1);
            Map<Integer, Integer> maps = Maps.uniqueIndex(collectList, new Function<Integer, Integer>() {
                @Override
                public Integer apply(Integer i) {
                    return i;
                }
            });
            List<MusicInfo> musicInfoList = (List<MusicInfo>) (List<?>) list;
            List<MusicInfo> result = new ArrayList<>();
            if (currentMusicInfo.getId() != null) {
                result.add(currentMusicInfo);
            }
            for (MusicInfo musicInfo : musicInfoList) {
                if (maps.get(musicInfo.getId().intValue()) != null) {
                    musicInfo.setCollected(1);
                } else {
                    musicInfo.setCollected(0);
                }
                // musicid已经单独放到了result列表第一个，这里需要把它排除掉 2018/9/17/ by kml
                if (musicInfo.getId() != null && !musicInfo.getId().equals(musicid)) {
                    result.add(musicInfo);
                }
            }
            return result;
        } else {
            List<Long> musicIdList = null;
            //第一步失败，查mysql
            if (res == 1) {
                Long offset = Long.valueOf(iOffset.toString());
                dto.setLimit(1000);
                dto.setOffset(0L);
                dto.setUserId(u.getId());
                List<Long> musicIdListTemp = musicMapper.queryIdList(dto);
                redisService.deleteKey(MUSIC_ID_KEY);
                for (int i = 0; i < musicIdListTemp.size(); i++) {
                    rwRedisService.rightPush(MUSIC_ID_KEY, musicIdListTemp.get(i));
                }
                //listOperations.leftPush(MUSIC_ID_KEY, musicIdList_temp);
                dto.setLimit(size);
                dto.setOffset(offset);
                musicIdList = musicMapper.queryIdList(dto);
            }
            //第二步失败，直接使用redis里的
            if (res == 2) {
                musicIdList = (List<Long>) (List<?>) list;
            }
            if (musicIdList == null || musicIdList.size() <= 0) {
                return null;
            }
            //无论第几步失败，musicInfo都是根据musicIdList查询数据库获取
            List<Music> musicList = musicMapper.queryByIdList(musicIdList, u.getId());
            List<MusicInfo> musicInfoList = new ArrayList<MusicInfo>();
            musicInfoList = ConvertUtil.musicsToMusicsInfo(musicList);
            for (MusicInfo musicInfo : musicInfoList) {
                rwRedisService.hput(MUSIC_KEY, musicInfo.getId(), musicInfo);
            }
            List<MusicInfo> result = new ArrayList<MusicInfo>();
            if (currentMusicInfo.getId() != null) {
                result.add(currentMusicInfo);
            }
            result.addAll(musicInfoList);
            return result;
        }
    }


    /**
     * 获取我收藏的音乐
     *
     * @param page
     * @param size
     * @return
     */
    @Override
    public List<MusicInfo> getMyCollectMusics(Integer page, Integer size) {

        UserInfo u = GlobalController.getNowUser();
        Integer iOffset = (page - 1) * size;
        Response r = new Response();
        //调用redis公共查询方法
        List<Object> list = (List<Object>) redisService.listFromRedis(page, size, MUSIC_COLLECT_KEY + u.getId(), MUSIC_KEY, r);
        int res = Integer.parseInt(r.getData().toString());
        if (res == 0) {
            return (List<MusicInfo>) (List<?>) list;
        } else {
            List<Long> musicIdList = null;
            //第一步失败，查mysql获取fansList
            if (res == 1) {
                MusicQueryDto musicQueryDto = new MusicQueryDto();
                musicQueryDto.setUserId(u.getId());
                musicQueryDto.setLimit(1000);
                musicQueryDto.setOffset(0L);
                List<Long> musicIdListTemp = musicCollectMapper.selectMusicIds(musicQueryDto);
                redisService.deleteKey(MUSIC_COLLECT_KEY + u.getId());
                //listOperations.leftPush(MUSIC_COLLECT_KEY+u.getId(), musicIdList_temp);
                for (int i = 0; i < musicIdListTemp.size(); i++) {
                    rwRedisService.rightPush(MUSIC_COLLECT_KEY + u.getId(), musicIdListTemp.get(i));
                }
                Long offset = Long.valueOf(iOffset.toString());
                musicQueryDto.setLimit(size);
                musicQueryDto.setOffset(offset);
                musicIdList = musicCollectMapper.selectMusicIds(musicQueryDto);
            }
            //第二步失败，直接使用redis里的musicIdList
            if (res == 2) {
                musicIdList = (List<Long>) (List<?>) list;
            }
            if (musicIdList == null || musicIdList.size() <= 0) {
                return null;
            }
            //无论第几步失败，musicInfo都是根据musicIdList查询数据库获取
            List<Music> musicList = musicMapper.queryByIdList(musicIdList, u.getId());
            List<MusicInfo> musicInfoList = new ArrayList<MusicInfo>();
            musicInfoList = ConvertUtil.musicsToMusicsInfo(musicList);
            for (MusicInfo musicInfo : musicInfoList) {
                rwRedisService.hput(MUSIC_KEY, musicInfo.getId(), musicInfo);
            }
            return musicInfoList;
        }


    }

    /**
     * 收藏音乐
     *
     * @param musicid
     * @return
     */
    @Override
    public boolean collectMusic(Long musicid) {

        UserInfo u = GlobalController.getNowUser();
        long nowSeconds = System.currentTimeMillis() / 1000;
        MusicCollect musicCollect = musicCollectMapper.findOneByMusicIdIdAndUserid(musicid, u.getId());
        if (null != musicCollect) {
            throw new MusicException(StatusCode.MUSIC_COLLECTED);
        }
        musicCollect = new MusicCollect();
        musicCollect.setMusicId(musicid);
        musicCollect.setUserId(u.getId());
        musicCollect.setCreatedTime(nowSeconds);
        if (musicCollectMapper.add(musicCollect) <= 0) {
            throw new VideoException(StatusCode.MUSIC_EXCEPTION);
        } else {
            rwRedisService.leftPush(MUSIC_COLLECT_KEY + u.getId(), musicid);
            return true;
        }
    }

    /**
     * 取消收藏
     */
    @Override
    public boolean cancelCollect(Long musicid) {
        UserInfo u = GlobalController.getNowUser();
        MusicCollect musicCollect = musicCollectMapper.findOneByMusicIdIdAndUserid(musicid, u.getId());
        if (null == musicCollect) {
            throw new MusicException(StatusCode.MUSIC_UNCOLLECT);
        }
        if (musicCollectMapper.deleteCollect(musicCollect) <= 0) {
            throw new VideoException(StatusCode.MUSIC_EXCEPTION);
        } else {
            rwRedisService.opsForList().remove(MUSIC_COLLECT_KEY + u.getId(), 0, musicid);
            return true;
        }
    }

    /**
     * 新增音乐
     */
    @Override
    public MusicInfo newMusic(MusicDto dto) {
        UserInfo u = GlobalController.getNowUser();
        Music music = new Music();
        BeanUtils.copyProperties(dto, music);
        long nowSeconds = System.currentTimeMillis() / 1000;
        music.setCreatedTime(nowSeconds);
        music.setUserId(u.getId());
        musicMapper.insert(music);
        MusicInfo musicInfo = new MusicInfo();
        BeanUtils.copyProperties(music, musicInfo);
        // 该处新增音乐为从用户上传视频中剥离处的音乐，不计入缓存
        // 维护一份MusicId 用于分页
        //listOperations.leftPush(MUSIC_ID_KEY, musicInfo.getId());
        // 维护一份MusicInfo 实体用于查询
        //hashOperations.put(MUSIC_KEY, musicInfo.getId(), musicInfo);
        return musicInfo;
    }

    @Override
    public List<Music> getAll() {
        return musicMapper.getAll();
    }


    @Override
    public Music getMusicById(Long musicid) {
        return musicMapper.selectByPrimaryKey(musicid);
    }


    @Override
    public List<Music> getMusicByIds(List<Long> ids) {
        List<Music> list = new ArrayList<Music>();
        if (ids != null && !ids.isEmpty()) {
            list = musicMapper.getMusicByIds(ids);
        }
        return list;
    }


    @Override
    public boolean updateMusicOrginalMusicUrl(Long videoId, Long userId, String musicUrl) {
        Music music = new Music();
        music.setMusic(musicUrl);
        music.setType(1); //0为系统，1为用户视频提取
        music.setUsed(1);
        music.setUserId(userId);
        music.setVideoId(videoId);
        music.setCreatedTime(System.currentTimeMillis() / 1000);
        music.setCover(ConstantValue.DEFAULT_MUSIC_COVER); //设置默认音乐封面
        //music.(duration);
        musicMapper.insertSelective(music);
        videoService.updateVideoMusic(videoId, music.getId());
        return true;
    }


    @Override
    public boolean updateMusicOrginalMusicUrlV1(Long videoId, Long userId, String musicUrl, Double duration) {
        Music music = new Music();
        music.setMusic(musicUrl);
        music.setType(1); //0为系统，1为用户视频提取
        music.setUsed(1);
        music.setUserId(userId);
        music.setVideoId(videoId);
        music.setDuration(duration);
        music.setCreatedTime(System.currentTimeMillis() / 1000);
        music.setCover(ConstantValue.DEFAULT_MUSIC_COVER); //设置默认音乐封面
        //music.(duration);
        musicMapper.insertSelective(music);
        videoService.updateVideoMusic(videoId, music.getId());
        return true;
    }
}
